#include "stdafx.h"

#include "Engine.h"


// AB Log Id
int g_ABLogId = 0;


 // Simple bitboard Negamax
////////////////////////////////////////////////////////////////////////////////



 // Simple bitboard Negamax - test DB lookup
////////////////////////////////////////////////////////////////////////////////

//int NegamaxEndGameDB(int depth, BitBoard *bb, bool bWhite, BitBoardMove* pbbMove )
//{
//	// return evaluation
//	if(depth <= 0)
//	{
//		if(TestJump(bb, bWhite) == false)
//		{
//			uint8 dtm;
//			int eval = DbReader::ReaderDbLookup(bb, bWhite ? WHITE : BLACK, &dtm);
//			switch(eval)
//			{
//			case WIN:
//				eval = GAME_WIN - dtm;
//				break;
//			case LOSS:
//				eval = GAME_LOSS + dtm;
//				break;
//			default:
//				eval = 0;
//				break;
//			}
//
//			return eval;
//		}
//	}
//
//	// generate bitboard moves
//	BitBoardMove bitMoves[MAX_MOVES];
//	int moveCount = GenerateBitBoardMoves(bb, bWhite, bitMoves);
//	if(moveCount == 0)
//		return GAME_LOSS;
//
//	// iterate through moves
//	BitBoardMove bbBestMove;
//	int bestResult = GAME_LOSS - 1;
//	for(int i = 0; i < moveCount; i++)
//	{
//		ToggleMove(bb, &bitMoves[i]);
//
//		// call next level
//		int result = -NegamaxEndGameDB(depth - 1, bb, ! bWhite, NULL );
//
//		ToggleMove(bb, &bitMoves[i]);
//
//		// compare result
//		if(result >= bestResult)
//		{
//			memcpy(&bbBestMove, &bitMoves[i], sizeof(BitBoardMove));
//			bestResult = result;
//		} // if
//
//	} // for
//
//	if(pbbMove)
//		memcpy(pbbMove, &bbBestMove, sizeof(BitBoardMove));
//
//	return bestResult;
//}
//






 // PRINCIPAL VARIATION SEARCH
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


//int PVSearchDeep(DWORD dwMaxTime, int depth, BitBoard *bb, bool bWhite,  int alpha, int beta, ZOBRIST_KEY zkeyBoard, bool is_pv, BitBoardMove* pbbMove = NULL)
//{
//	iNumberOfNodes++;
//
//	// check the time
//	if( (iNumberOfNodes & 0x3FF) == 0)
//	{
//		if(GetTickCount() - dwStartTime > dwMaxTime)
//		{
//			return GAME_TIMEOUT;
//		}
//	}
//
//	int ply = iMaxDepth - depth;
//	int oldalpha = alpha;
//	int oldbeta = beta;
//
//
//	// probe endgame database
//	if(TestJump(bb, bWhite) == false && depth <= 0  && bUseEndGameDB)
//	{
//		int figureCount = BitCount(bb->wm) + BitCount(bb->wk) + BitCount(bb->bm) + BitCount(bb->bk);
//		if(figureCount < 7)
//		{
//			if(IsDraw(bb, zkeyBoard) == true)
//				return 0;
//
//			uint8 dtm;
//			int eval = DbReader::ReaderDbLookup(bb, bWhite ? WHITE : BLACK, &dtm);
//			switch(eval)
//			{
//			case WIN:
//				return eval = GAME_WIN - dtm - (iMaxDepth - depth);
//			case LOSS:
//				return eval = GAME_LOSS + dtm + (iMaxDepth - depth);
//			case DRAW:
//				return 0;
//			}
//		}
//	}
//
//
//
//	//if(depth == 0) 
//	//	return Quiescence(bb, bWhite, alpha, beta, zkeyBoard);
//	if(depth <= 0) 
//	{
//		if(TestJump(bb, bWhite) == false)
//		{
//			return bUsePositionEvaluation ? PositionEvaluation(bb, bWhite, zkeyBoard) : BasicEvaluation(bb, bWhite);
//		}
//	}
//
//	if(IsDrawByRepetition(zkeyBoard))
//		return 0;
//
//	// probe cache
//	int cacheValue = 0;
//	int cacheAlpha = alpha;
//	int cacheBeta = beta;
//	BitBoardMove bbTTMove;
//	memset(&bbTTMove, 0, sizeof(bbTTMove));
//	// if(oldalpha != oldbeta - 1)
//	{
//		if(Cache_Lookup(zkeyBoard, depth, cacheValue, cacheAlpha, cacheBeta, bWhite, pbbMove) == true)
//		{
//			return cacheValue;
//		}
//	}
//
//	ZOBRIST_KEY zkeyTTMove = 0;
//	if(bbTTMove.wm != 0 || bbTTMove.wm != 0 || bbTTMove.bm != 0 || bbTTMove.bk != 0)
//		zkeyTTMove = GenerateBoardKey(&bbTTMove, bWhite);
//
//
//
//	// generate bitboard moves
//	BitBoardMove bitMoves[MAX_MOVES];
//	BitBoardMove *pBitMove[MAX_MOVES];
//	int moveCount = CzechMoveGen::GenerateBitBoardMoves(bb, bWhite, bitMoves);
//	if(moveCount == 0)
//		return GAME_LOSS + (iMaxDepth - depth);
//
//	for(int i = 0; i < moveCount; i++)
//	{
//		pBitMove[i] = &bitMoves[i];
//		pBitMove[i]->score = 0;
//		if(GenerateBoardKey(pBitMove[i], bWhite) == zkeyTTMove)
//			pBitMove[i]->score = VALUE_TT_MOVE;
//	}
//
//	// do updates
//	HistoryUpdateScore(bitMoves, moveCount, bWhite);
//	UpdateKillerScore(bitMoves, moveCount, bWhite, ply);
//
//
//	// sort moves
//	MoveQuickSort(pBitMove, 0, moveCount - 1);
//
//	// iterate through moves
//	BitBoardMove bbBestMove;
//	int bestResult = GAME_LOSS - 1;
//	int b = beta;
//	BYTE hashF = hashfALPHA;
//
//	memset(&bbBestMove, 0, sizeof(BitBoardMove));
//
//	bool bPVSearch = true;
//	bool bFirstMove = true;
//	int result = 0;
//
//	for(int i = 0; i < moveCount; i++)
//	{
//		// do move
//		ZOBRIST_KEY zkeyMove = GenerateBoardKey(pBitMove[i], bWhite);
//
//		ToggleMove(bb, pBitMove[i]);
//		zkeyBoard ^= zkeyMove;
//		DrawPushMove(zkeyBoard);
//	
//
//		if(!is_pv || depth < 3)
//		{
//			result = -PVSearchDeep(dwMaxTime, depth - 1, bb, ! bWhite, -beta, -alpha, zkeyBoard, false);
//		}
//		else
//		{
//			if(bPVSearch == true)
//			{
//				result = -PVSearchDeep(dwMaxTime, depth - 1, bb, ! bWhite, -beta, -alpha, zkeyBoard, is_pv);
//
//			} 
//			else
//			{
//				// zero-window search
//				int nullResult = -PVSearchDeep(dwMaxTime, depth - 1, bb, ! bWhite, -alpha-1, -alpha, zkeyBoard, false);
//				if(nullResult > alpha)
//				{
//					result = -PVSearchDeep(dwMaxTime, depth - 1, bb, ! bWhite, -beta, -alpha, zkeyBoard, is_pv);
//				}
//			}
//		}	
//		
//		DrawPopMove(zkeyBoard);	
//		zkeyBoard ^= zkeyMove;
//		ToggleMove(bb, pBitMove[i]);
//
//		if(abs(result) == GAME_TIMEOUT)
//			return GAME_TIMEOUT;
//
//
//	
//		// compare result
//		if(result > bestResult || bFirstMove == true)
//		{
//			bestResult = result;
//			bFirstMove = false;
//			memcpy(&bbBestMove, pBitMove[i], sizeof(BitBoardMove));
//
//			// if(oldalpha != oldbeta - 1)
//			{
//				if(TestJump(bb, bWhite) == false)
//					IncrementMove(pBitMove[i], bWhite, ply);
//			}
//			
//			if(result > alpha)
//			{
//				bPVSearch = false;
//				hashF = hashfVALUE;
//				alpha = result;
//			}
//		} // if
//		if(result >= beta)
//		{
//			// if(oldalpha != oldbeta - 1)
//			{
//				if(TestJump(bb, bWhite) == false)
//				{
//					IncrementMove(pBitMove[i], bWhite, depth * depth);
//					SetKiller(zkeyMove, ply);
//				}
//			}
//
//			hashF = hashfBETA;
//			//result = beta;
//			// alpha = beta;
//			alpha = result;
//			break;
//		}
//	} // for
//
//	// store value to cache
//	if(hashF == hashfBETA)
//		cacheValue = beta;
//	else 
//	{
//		cacheValue = alpha;
//		// bestResult = alpha;
//	}
//
//
//	//if(oldalpha == oldbeta - 1 /*&& (hashF == hashfALPHA || hashF == hashfBETA )*/)
//	//{}
//	//else
//	{
//		Cache_Store(zkeyBoard, depth, cacheValue, hashF, bWhite, &bbBestMove);
//	}
//
//
//	if(pbbMove)
//		memcpy(pbbMove, &bbBestMove, sizeof(BitBoardMove));
//
//	return alpha;
//}
//
//
//int PVSearchBB(BitBoard* bb, bool bWhite, DWORD dwCompTime, BitBoardMove* pbbMove, int iCacheSize)
//{
//	int bestEvaluation = GAME_LOSS - 1;
//	iNumberOfNodes = 0;
//
//	Cache_Allocate(iCacheSize);
//	EvalCache_Allocate(iCacheSize);
//	HistoryTableDoAge();
//	ClearDrawRepetition();
//
//	
//	dwStartTime = GetTickCount();
//
//	ZOBRIST_KEY zkeyBoard = GenerateBoardKey(bb, bWhite);
//
//	BitBoardMove bbMove, bbBestMove;
//	memset(&bbBestMove, 0, sizeof(BitBoardMove));
//	memset(&bbMove, 0, sizeof(BitBoardMove));
//
//	for(int depth = 1; depth < 99; depth++)
//	{
//		iMaxDepth = depth;
//		if(GetTickCount() - dwStartTime > dwCompTime)
//			break;
//		int eval = PVSearchDeep(dwCompTime, depth, bb, bWhite, GAME_LOSS - 1,  GAME_WIN + 1, zkeyBoard, true, &bbMove);
//
//		// check the best move, is it better?
//		if(/*eval > bestEvaluation &&*/ abs(eval) != GAME_TIMEOUT)
//		{
//			bestEvaluation = eval;
//			memcpy(&bbBestMove, &bbMove, sizeof(BitBoardMove));
//		}
//		if(abs(eval) != GAME_TIMEOUT)
//		{
//			iReachedDepth = depth;
//		}
//	}
//
//	Cache_Free();
//	EvalCache_Free();
//
//	iNodesPerSec = iNumberOfNodes / (dwCompTime / 1000);
//
//
//	memcpy(pbbMove, &bbBestMove, sizeof(BitBoardMove));
//	return bestEvaluation;
//}
//
